package com.imay.live.media;

import android.app.Service;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Surface;
import android.view.View;

import com.imay.base.helper.NetworkHelper;
import com.imay.live.helper.DialogFragmentHelper;
import com.imay.live.helper.ThreadManager;
import com.imay.live.utils.ImayLogUtil;
import com.tencent.rtmp.ITXLivePushListener;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXLivePushConfig;
import com.tencent.rtmp.TXLivePusher;
import com.tencent.rtmp.ui.TXCloudVideoView;

import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by jeaman on 2017/4/20.
 */

public class LivePusher implements ITXLivePushListener{
    private final static  String TAG = "LivePusher";

    private TXLivePushConfig mLivePushConfig;
    private TXLivePusher mLivePusher;

    protected TXCloudVideoView mVideoView;
    private PushListener mListener;
    private boolean mPushDisconnect;    //推流是否已断开
    private boolean mPause; //是否进入后台
    private Timer mTimer;
    private TimerTask mReconnectTimerTask;


    private boolean mFrontCamera = true;    //默认前置摄像头
//    private boolean mVideoEncoderXMirror = mFrontCamera;    //默认开启观众端镜像
    private boolean mHWVideoEncode = false;
    private boolean mFlashTurnOn = false;
    private boolean mTouchFocus = true;
    private boolean mPortrait = true;         //手动切换，横竖屏推流
    private boolean mVideoPublish = false;  //是否在推流
    private String mPushUrl;
    private int mBeautyLevel = 8;
    private int mWhiteningLevel = 7;
    private int mRuddyLevel = 7;
    private PushEventListener pushEventListener;
    private PushBGMListener pushBGMListener;
    private String BGMPath;

    private final PhoneStateListener mPhoneStateListener = new PhoneStateListener(){
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            switch(state){
                //电话等待接听
                case TelephonyManager.CALL_STATE_RINGING:
                    pausePusher();
                    break;
                //电话接听
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    pausePusher();
                    break;
                //电话挂机
                case TelephonyManager.CALL_STATE_IDLE:
                    resumePusher();
                    break;
            }
        }
    };

    public LivePusher(Context context, TXCloudVideoView videoView) {
        mLivePusher = new TXLivePusher(context);
        mLivePushConfig = new TXLivePushConfig();
//        mLivePushConfig.setConnectRetryInterval(3);
//        mLivePushConfig.setConnectRetryCount(Integer.MAX_VALUE);    //重试次数
        mLivePusher.setConfig(mLivePushConfig);
        mVideoView = videoView;

        TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
        tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    public void resumePusher() {
        mPause = false;
        if (mVideoView != null) {
            mVideoView.onResume();
        }

        //恢复推流
        if (mVideoPublish) {
//            mLivePusher.resumePusher();
            startPusher();
//            Log.e(TAG, "resumePusher: ");

        }
    }

    public void pausePusher() {
        mPause = true;
        if (mVideoView != null) {
            mVideoView.onPause();
        }

        if (mVideoPublish) {
//            mLivePusher.pausePusher();
            mLivePusher.stopPusher();
        }
    }

    public void onDestroy() {
        mListener = null;
        stopPublish();

        if (mVideoView != null) {
            mVideoView.onDestroy();
        }
    }

    public void setMainPublisher() {
        mLivePusher.setVideoQuality(TXLiveConstants.VIDEO_QUALITY_LINKMIC_MAIN_PUBLISHER, true, false); //连麦模式：大主播
    }

    public void setSubPublisher() {
        mLivePusher.setVideoQuality(TXLiveConstants.VIDEO_QUALITY_LINKMIC_SUB_PUBLISHER, true, false); //连麦模式：小主播
    }

    public void setNormalPublisher() {
        mLivePusher.setVideoQuality(TXLiveConstants.VIDEO_QUALITY_HIGH_DEFINITION, true, false); //非连麦模式：高清
    }

    public void startPreview(Bitmap watermark) {
        mVideoView.setVisibility(View.VISIBLE);
        if (watermark != null) {
            mLivePushConfig.setWatermark(watermark, 469, 112);
        }

        mLivePushConfig.setTouchFocus(false);   //关闭手动对焦
//        int customModeType = 0;
//        mLivePushConfig.setCustomModeType(customModeType);

//        mLivePushConfig.setPauseImg(300, 10);
//        Bitmap pauseImg = decodeResource(getResources(), R.mipmap.pause_publish);
//        mLivePushConfig.setPauseImg(pauseImg);
        mLivePushConfig.setPauseFlag(TXLiveConstants.PAUSE_FLAG_PAUSE_VIDEO | TXLiveConstants.PAUSE_FLAG_PAUSE_AUDIO);

//        mLivePushConfig.setBeautyFilter(mBeautyLevel, mWhiteningLevel, mRuddyLevel);
        mLivePushConfig.setBeautyFilter(mBeautyLevel, mWhiteningLevel);
//        mLivePushConfig.setVideoFPS(24);
        mLivePushConfig.setFrontCamera(mFrontCamera);
        mLivePushConfig.setVideoEncoderXMirror(mFrontCamera);
//        mLivePushConfig.enableNearestIP(false);

        mLivePusher.setConfig(mLivePushConfig);
        mLivePusher.setMirror(mFrontCamera);
        mLivePusher.setPushListener(this);
        mLivePusher.startCameraPreview(mVideoView);
//        mLivePusher.startScreenCapture();
    }

    public boolean startPublishRtmp(String rtmpUrl) {
        if (rtmpUrl == null) {
            return false;
        }
        mVideoPublish = true;
        mPushUrl = rtmpUrl.trim();
        startPusher();
        return true;
    }

    public void startPusher() {
        cancelReconnect();
        if (mPushUrl != null) {
            if (mLivePusher.isPushing()) {
                mLivePusher.stopPusher();
            }
            mLivePusher.startPusher(mPushUrl);
        }
    }

    public void stopPublish() {
        mVideoPublish = false;

        if (mLivePusher != null) {
            mLivePusher.stopBGM();
            mLivePusher.stopCameraPreview(false);
            mLivePusher.stopScreenCapture();
            mLivePusher.setPushListener(null);
            mLivePusher.stopPusher();
            mVideoView.setVisibility(View.GONE);
        }

        if (mLivePushConfig != null) {
            mLivePushConfig.setPauseImg(null);
        }
    }

    public void setBeautyFilter(int beautyLevel, int whiteningLevel, int ruddyLevel) {
        mBeautyLevel = beautyLevel;
        mWhiteningLevel = whiteningLevel;
        mRuddyLevel = ruddyLevel;
        if (mLivePusher != null) {
//            mLivePusher.setBeautyFilter(0, beautyLevel, whiteningLevel, ruddyLevel);
            mLivePusher.setBeautyFilter(beautyLevel, whiteningLevel);
        }
    }

    public int getBeautyLevel() {
        return mBeautyLevel;
    }

    public int getWhiteningLevel() {
        return mWhiteningLevel;
    }

    public int getRuddyLevel() {
        return mRuddyLevel;
    }

    private void fixOrAdjustBitrate(int mode) {
        if (mLivePushConfig == null || mLivePusher == null) {
            return;
        }

        switch (mode) {
            case 4: /*720p*/
                if (mLivePusher != null) {
//                    mLivePushConfig.setVideoResolution(TXLiveConstants.VIDEO_RESOLUTION_TYPE_720_1280);
//                    mLivePushConfig.setAutoAdjustBitrate(false);
//                    mLivePushConfig.setVideoBitrate(1500);
//                    mLivePusher.setConfig(mLivePushConfig);
                    mLivePusher.setVideoQuality(TXLiveConstants.VIDEO_QUALITY_SUPER_DEFINITION, true, false);
                    //超清默认开启硬件加速
                    if (Build.VERSION.SDK_INT >= 18) {
                        mHWVideoEncode = true;
                    }
//                    mBtnHWEncode.getBackground().setAlpha(255);
                }
                break;
            case 3: /*540p*/
                if (mLivePusher != null) {
//                    mLivePushConfig.setVideoResolution(TXLiveConstants.VIDEO_RESOLUTION_TYPE_540_960);
//                    mLivePushConfig.setAutoAdjustBitrate(false);
//                    mLivePushConfig.setVideoBitrate(1000);
//                    mLivePusher.setConfig(mLivePushConfig);
                    mLivePusher.setVideoQuality(TXLiveConstants.VIDEO_QUALITY_HIGH_DEFINITION, true, false);
                    mHWVideoEncode = false;
//                    mBtnHWEncode.getBackground().setAlpha(100);
                }
                break;
            case 2: /*360p*/
                if (mLivePusher != null) {
                    mLivePusher.setVideoQuality(TXLiveConstants.VIDEO_QUALITY_STANDARD_DEFINITION, true, false);
//                    mLivePushConfig.setVideoResolution(TXLiveConstants.VIDEO_RESOLUTION_TYPE_360_640);
                    //标清默认开启了码率自适应，需要关闭码率自适应
                    mLivePushConfig.setAutoAdjustBitrate(false);
                    mLivePushConfig.setVideoBitrate(700);
                    mLivePusher.setConfig(mLivePushConfig);
                    //标清默认关闭硬件加速
                    mHWVideoEncode = false;
//                    mBtnHWEncode.getBackground().setAlpha(100);
                }
                break;

            case 1: /*自动*/
                if (mLivePusher != null) {
//                    mLivePushConfig.setVideoResolution(TXLiveConstants.VIDEO_RESOLUTION_TYPE_360_640);
//                    mLivePushConfig.setAutoAdjustBitrate(true);
//                    mLivePushConfig.setAutoAdjustStrategy(TXLiveConstants.AUTO_ADJUST_BITRATE_STRATEGY_1);
//                    mLivePushConfig.setMaxVideoBitrate(1000);
//                    mLivePushConfig.setMinVideoBitrate(400);
//                    mLivePushConfig.setVideoBitrate(700);
//                    mLivePusher.setConfig(mLivePushConfig);
                    mLivePusher.setVideoQuality(TXLiveConstants.VIDEO_QUALITY_STANDARD_DEFINITION, true, false);
                    //自动默认关闭硬件加速
                    mHWVideoEncode = false;
//                    mBtnHWEncode.getBackground().setAlpha(100);
                }
                break;
            default:
                break;
        }
    }

    //切换摄像头
    public void switchCamera() {
        mFrontCamera = !mFrontCamera;

        mLivePusher.switchCamera();
        mLivePushConfig.setFrontCamera(mFrontCamera);

        mLivePusher.setMirror(mFrontCamera);
        //设置镜像
//        mLivePusher.stopCameraPreview(false);
//        mVideoEncoderXMirror = mFrontCamera;
//        mLivePushConfig.setFrontCamera(mFrontCamera);
//        mLivePushConfig.setVideoEncoderXMirror(mVideoEncoderXMirror);
//        mLivePusher.setConfig(mLivePushConfig);
//        mLivePusher.startCameraPreview(mVideoView);
    }

    //闪光灯
    protected void turnOnFlashLight() {
        if (mLivePusher == null) {
            return;
        }

        mFlashTurnOn = !mFlashTurnOn;
        if (!mLivePusher.turnOnFlashLight(mFlashTurnOn)) {
        }
    }

    //对焦
    protected void setTouchFocus() {
        if (mFrontCamera) {
            return;
        }

        mTouchFocus = !mTouchFocus;
        mLivePushConfig.setTouchFocus(mTouchFocus);

        if (mLivePusher.isPushing()) {
            mLivePusher.stopCameraPreview(false);
            mLivePusher.startCameraPreview(mVideoView);
        }
    }

    public void setMotionTmpl(String path) {
        if (mLivePusher == null) {
            return;
        }
        mLivePusher.setMotionTmpl(path);
    }

    //横竖屏推流切换
    protected void changeOrientation() {
        mPortrait = !mPortrait;
        int renderRotation = 0;
        if (mPortrait) {
            mLivePushConfig.setHomeOrientation(TXLiveConstants.VIDEO_ANGLE_HOME_DOWN);
            renderRotation = 0;
        } else {
            mLivePushConfig.setHomeOrientation(TXLiveConstants.VIDEO_ANGLE_HOME_RIGHT);
            renderRotation = 270;
        }
        mLivePusher.setRenderRotation(renderRotation);
        mLivePusher.setConfig(mLivePushConfig);
    }

    public void onActivityRotation(int mobileRotation) {
        // 自动旋转打开，Activity随手机方向旋转之后，需要改变推流方向
        int pushRotation = TXLiveConstants.VIDEO_ANGLE_HOME_DOWN;
        switch (mobileRotation) {
            case Surface.ROTATION_0:
                pushRotation = TXLiveConstants.VIDEO_ANGLE_HOME_DOWN;
                break;
            case Surface.ROTATION_90:
                pushRotation = TXLiveConstants.VIDEO_ANGLE_HOME_RIGHT;
                break;
            case Surface.ROTATION_270:
                pushRotation = TXLiveConstants.VIDEO_ANGLE_HOME_LEFT;
                break;
            default:
                break;
        }
        setHomeOrientation(pushRotation);
    }

    public void setHomeDownOrientation() {
        setHomeOrientation(TXLiveConstants.VIDEO_ANGLE_HOME_DOWN);
    }

    public void setHomeOrientation(int pushRotation) {
        mLivePusher.setRenderRotation(0); //因为activity也旋转了，本地渲染相对正方向的角度为0。
        mLivePushConfig.setHomeOrientation(pushRotation);
        mLivePusher.setConfig(mLivePushConfig);
    }

    public void setHardwareAcceleration(boolean hardwareEncode) {
        mLivePushConfig.setHardwareAcceleration(hardwareEncode ? TXLiveConstants.ENCODE_VIDEO_HARDWARE : TXLiveConstants.ENCODE_VIDEO_SOFTWARE);
        mLivePusher.setConfig(mLivePushConfig);
        mHWVideoEncode = false;
    }

    @Override
    public void onPushEvent(int event, Bundle param) {
        //错误还是要明确的报一下
        ImayLogUtil.log(TAG, "push event:" +event+"   event des:"+ param.getString(TXLiveConstants.EVT_DESCRIPTION));
//        if (event < 0) {
//            Log.e(TAG, "push error:" + param.getString(TXLiveConstants.EVT_DESCRIPTION));
//            if (event == TXLiveConstants.PUSH_ERR_OPEN_CAMERA_FAIL) {
//                stopPublish();
//            }
//        }
        switch (event) {
            case TXLiveConstants.PUSH_ERR_NET_DISCONNECT:
                mLivePusher.stopPusher();
                mPushDisconnect = true;
                tryReconnect();  //断开连接时继续尝试推流
                if (mListener != null) {
                    mListener.onPushNetDisconnect();
                }
                break;
            case TXLiveConstants.PUSH_EVT_PUSH_BEGIN: //开始推流
                mPushDisconnect = false;
                cancelReconnect();
                if (pushEventListener!=null){
                    pushEventListener.onRestartPush();
                }
                if (pushBGMListener!=null&&mLivePusher.playBGM(BGMPath)){
                    pushBGMListener.onPlayBGMSuccess();
                }
                if (mListener != null) {
                    mListener.onPushBegin();
                }
                break;
            case TXLiveConstants.PUSH_WARNING_NET_BUSY:
                if (mListener != null) {
                    mListener.onPushNetBusy();
                }
                break;
            case TXLiveConstants.PUSH_ERR_OPEN_CAMERA_FAIL:
                if (mListener != null) {
                    mListener.onPushOpenCameraFail();
                }
                break;
            case TXLiveConstants.PUSH_ERR_VIDEO_ENCODE_FAIL:
            case TXLiveConstants.PUSH_ERR_AUDIO_ENCODE_FAIL:
            case TXLiveConstants.PUSH_ERR_UNSUPPORTED_RESOLUTION:
            case TXLiveConstants.PUSH_ERR_UNSUPPORTED_SAMPLERATE:
                if (mListener != null) {
                    mListener.onPushDecodeFail();
                }
                break;
            case TXLiveConstants.PUSH_ERR_OPEN_MIC_FAIL:
                if (mListener != null) {
                    mListener.onPushOpenMicFail();
                }
                break;
            case TXLiveConstants.PUSH_WARNING_HW_ACCELERATION_FAIL:
                setHardwareAcceleration(false);
                break;
            case TXLiveConstants.PUSH_WARNING_RECONNECT:
                if (pushEventListener != null) {
                    pushEventListener.onDisconnet();
                }
                break;
        }
    }

    private boolean needReconnect() {
        if (!mVideoPublish || mPause || !NetworkHelper.getInstance().hasConnection()) {
            return false;
        }
        return true;
    }

    //尝试重连
    private void tryReconnect() {
//        if (!needReconnect()) {
//            return;
//        }
        cancelReconnect();
        mReconnectTimerTask = new TimerTask() {
            @Override
            public void run() {
                ThreadManager.post(new Runnable() {
                    @Override
                    public void run() {
                        if (needReconnect()) {
                            try {
                                startPusher();
                            } catch (Throwable e) {
                                Log.e(TAG, "start pusher error:" + e.toString());
                            }
                        }
                    }
                });
            }
        };
        if (mTimer == null) {
            mTimer = new Timer();
        }
        mTimer.schedule(mReconnectTimerTask, 3000, 3000);
    }

    private void cancelReconnect() {
        if (mReconnectTimerTask != null) {
            mReconnectTimerTask.cancel();
        }
    }

    @Override
    public void onNetStatus(Bundle status) {
        String str = getNetStatusString(status);
        Log.d(TAG, str);
    }

    //公用打印辅助函数
    protected String getNetStatusString(Bundle status) {
        String str = String.format("%-14s %-14s %-12s\n%-14s %-14s %-12s\n%-14s %-14s %-12s\n%-14s %-12s",
                "CPU:" + status.getString(TXLiveConstants.NET_STATUS_CPU_USAGE),
                "RES:" + status.getInt(TXLiveConstants.NET_STATUS_VIDEO_WIDTH) + "*" + status.getInt(TXLiveConstants.NET_STATUS_VIDEO_HEIGHT),
                "SPD:" + status.getInt(TXLiveConstants.NET_STATUS_NET_SPEED) + "Kbps",
                "JIT:" + status.getInt(TXLiveConstants.NET_STATUS_NET_JITTER),
                "FPS:" + status.getInt(TXLiveConstants.NET_STATUS_VIDEO_FPS),
                "ARA:" + status.getInt(TXLiveConstants.NET_STATUS_AUDIO_BITRATE) + "Kbps",
                "QUE:" + status.getInt(TXLiveConstants.NET_STATUS_CODEC_CACHE) + "|" + status.getInt(TXLiveConstants.NET_STATUS_CACHE_SIZE),
                "DRP:" + status.getInt(TXLiveConstants.NET_STATUS_CODEC_DROP_CNT) + "|" + status.getInt(TXLiveConstants.NET_STATUS_DROP_SIZE),
                "VRA:" + status.getInt(TXLiveConstants.NET_STATUS_VIDEO_BITRATE) + "Kbps",
                "SVR:" + status.getString(TXLiveConstants.NET_STATUS_SERVER_IP),
                "AVRA:" + status.getInt(TXLiveConstants.NET_STATUS_SET_VIDEO_BITRATE));
        return str;
    }

    public void setPushListener(PushListener listener) {
        this.mListener = listener;
    }
    public void setPushEventListener(PushEventListener pushEventListener) {
        this.pushEventListener = pushEventListener;
    }

    public interface PushListener {
        void onPushNetBusy();
        void onPushOpenCameraFail();
        void onPushOpenMicFail();
        void onPushDecodeFail();
        void onPushNetDisconnect();
        void onPushBegin();
    }
    public interface PushEventListener {
        void onDisconnet();
        void onRestartPush();
    }
    public interface PushBGMListener {
        void onPlayBGMSuccess();
    }

    public void setBGM(String path){
        if (mLivePusher!=null){
            BGMPath = path;
        }
    }
    public void pauseBGM(){
        if (mLivePusher!=null){
            mLivePusher.pauseBGM();
        }
    }
    public void resumeBGM(){
        if (mLivePusher!=null){
            mLivePusher.resumeBGM();
        }
    }

    public void setPushBGMListener(PushBGMListener pushBGMListener) {
        this.pushBGMListener = pushBGMListener;
    }
}
